#include "StdAfx.h"
#include "Sphere.h"
#include "Ray.h"
#include "Point3D.h"
CSphere::CSphere(const CPoint3D& _Centre, float _Radius) : CPrimitive()
, Centre(_Centre)
, Radius(_Radius)
{
}

CSphere::~CSphere(void)
{
}
void CSphere::SetCentre(CPoint3D& centre)
{
	Centre = centre;
}
void CSphere::SetRadius(float f)
{
	Radius = f;
}

CPoint3D& CSphere::GetCentre()
{
	return Centre;
}
float CSphere::GetRadius()
{
	return Radius;
}
float CSphere::Intersect(CRay& ray, CPoint3D& intersection, CPoint3D& normal)
{
	CPoint3D& dir = ray.GetDirection();	
	CPoint3D& origin = ray.GetOrigin();
	float a = dir.Dot(dir);
	float b = 2 * dir.Dot(ray.GetOrigin() - Centre);
	float c = Centre.Dot(Centre) + origin.Dot(origin) - 2 * origin.Dot(Centre) - Radius*Radius;

	float delta = b * b - 4 * a * c;
	float t;
	if (delta < EPSILON) return -1.f;
	if (delta > EPSILON)
	{
		delta = sqrt(delta);
		float t1 = 0.5f*(- b - delta) / a;
		float t2 = 0.5f*(- b + delta) / a;
		if (t1 < 0 && t2 < 0)
		{
			return -1.f;			
		}
		else if (t1 < 0)
		{
			t = t2;
		}
		else if (t2 < 0)
		{
			t = t1;
		}
		else
		{
			if (t1 < t2)
				t = t1;
			else
				t = t2;
		}
	}
	else
	{
		t = - 0.5f * b / a;
		if (t < 0) return -1.f;		
	}
	intersection = ray.GetOrigin() + ray.GetDirection() * t;
	normal = (intersection - Centre) / Radius;
	return t;
}
CPoint3D& CSphere::GetLightSource(CPoint3D& point)
{
	return Centre;
}